﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Resources;
using nsWeldController.Properties;

namespace nsWeldController
{
    public partial class DrawActions : UserControl
    {
        public List<DrawObject> drawList = new List<DrawObject>();
        private Point pointCurrent = new Point(0, 0);
        private IList<ActionParas> mActionList;
        private Pen pen;
        private float divisor = 1;      // 用于缩小输入坐标的除数，以在面板中显示完整的图形

        public DrawActions()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
        }

        public void DrawAll(IList<ActionParas> actionList)
        {
            mActionList = actionList;
            int actionCount = mActionList.Count;

            if (this.drawList != null)
            {
                this.drawList.Clear();
            }

            ResetPen();
            CalculateDivisor();
            if (divisor == 0)
            {
                return; // 窗口在AutoHide状态，该值可能为0
            }

            float originX = CWeldController.mDockSetParameter.originXSet;
            float originY = CWeldController.mDockSetParameter.originYSet;
            float x1 = originX;
            float y1 = originY;
            float x2 = originX;
            float y2 = originY;
            Line line;
            Arc arc;
            int radius;

            // 绘制原点
            Pen penTemp = new Pen(Color.Green, 1);
            penTemp.DashStyle = DashStyle.Solid;
            radius = Math.Min(this.Size.Width, this.Size.Height) / 35;
            Circle circle = new Circle(new PointF(originX / divisor, originY / divisor), radius, Color.Green, penTemp);
            this.AddToDrawList(circle);

            // 绘制动作
            foreach (ActionParas action in CWeldController.mDockSetParameter.mAutoActionList)
            {
                switch (action.Cmd)
                {
                    case WELD_ACTION.移动到:
                        x2 = action.Point1X + originX;
                        y2 = action.Point1Y + originY;
                        pen.DashStyle = DashStyle.Dash;
                        line = new Line(x1 / divisor, y1 / divisor, x2 / divisor, y2 / divisor, pen);
                        this.AddToDrawList(line);
                        x1 = x2;
                        y1 = y2;
                        break;

                    case WELD_ACTION.圆弧插补:
                        // 先画一条到圆弧起点的直线
                        float startX;
                        float startY;
                        float endX;
                        float endY;
                        AnalyseMode(action, out startX, out startY, out endX, out endY);
                        pen.DashStyle = DashStyle.Dash;
                        line = new Line(x1 / divisor, y1 / divisor, startX / divisor, startY / divisor, pen);
                        this.AddToDrawList(line);
                        x1 = endX;
                        y1 = endY;

                        float startAngel = 0;
                        float endAngel = 90;
                        Pen penTemp1 = (Pen)pen.Clone();
                        if (action.Mode <= 4)
                        {
                            startAngel = (action.Mode - 1) * 90;
                            penTemp1.EndCap = LineCap.NoAnchor;
                            penTemp1.StartCap = LineCap.ArrowAnchor;
                        }
                        else
                        {
                            startAngel = (action.Mode - 5) * 90;
                            penTemp1.EndCap = LineCap.ArrowAnchor;
                            penTemp1.StartCap = LineCap.NoAnchor;
                        }
                        endAngel = 90;
                        radius = action.Radius;
                        penTemp1.DashStyle = DashStyle.Solid;
                        arc = new Arc(new PointF((action.Point1X + originX) / divisor, (action.Point1Y + originY) / divisor), radius / divisor, startAngel, endAngel, penTemp1);
                        this.AddToDrawList(arc);
                        break;

                    case WELD_ACTION.直线插补:
                        // 先画一条到直线起点的直线
                        x2 = action.Point1X + originX;
                        y2 = action.Point1Y + originY;
                        pen.DashStyle = DashStyle.Dash;
                        line = new Line(x1 / divisor, y1 / divisor, x2 / divisor, y2 / divisor, pen);
                        this.AddToDrawList(line);

                        x1 = action.Point1X + originX;
                        y1 = action.Point1Y + originY;
                        x2 = action.Point2X + originX;
                        y2 = action.Point2Y + originY;
                        pen.DashStyle = DashStyle.Solid;
                        line = new Line(x1 / divisor, y1 / divisor, x2 / divisor, y2 / divisor, pen);
                        this.AddToDrawList(line);
                        x1 = x2;
                        y1 = y2;
                        break; ;

                    case WELD_ACTION.点胶开:
                        pen.Color = Color.Orange;
                        pen.DashStyle = DashStyle.Solid;
                        break;

                    case WELD_ACTION.点胶关:
                        pen.Color = Color.Black;
                        pen.DashStyle = DashStyle.Dash;
                        break;

                    case WELD_ACTION.Z轴压下:
                        pen.Width = 4;
                        break;

                    case WELD_ACTION.Z轴抬起:
                        pen.Width = 2;
                        break;

                    default:
                        break;
                }
            }

            Invalidate(true);
        }

        private void ResetPen()
        {
            if (pen == null)
            {
                pen = new Pen(Color.Black, 2);
            }
            else
            {
                pen.Color = Color.Black;
                pen.Width = 2;
            }
            pen.DashStyle = DashStyle.Dash;
            pen.StartCap = LineCap.NoAnchor;
            pen.EndCap = LineCap.ArrowAnchor;
        }

        /// <summary>
        /// 计算divisor，该值是用于将输入坐标缩小，以在面板中显示完整的图形
        /// </summary>
        private void CalculateDivisor()
        {
            float div = 1;
            int padding = 10;
            int originX = CWeldController.mDockSetParameter.originXSet;
            int originY = CWeldController.mDockSetParameter.originYSet;
            int maxX = originX + padding;
            int maxY = originY + padding;
            CalculateDivisor(maxX, maxY, ref div);

            maxX = pointCurrent.X + padding;
            maxY = pointCurrent.Y + padding;
            CalculateDivisor(maxX, maxY, ref div);

            foreach (ActionParas action in CWeldController.mDockSetParameter.mAutoActionList)
            {
                if (action.Cmd == WELD_ACTION.移动到)
                {
                    maxX = action.Point1X;
                    maxY = action.Point1Y;
                }
                else if (action.Cmd == WELD_ACTION.直线插补)
                {
                    maxX = Math.Max(action.Point1X, action.Point2X);
                    maxY = Math.Max(action.Point1Y, action.Point2Y);
                }
                else if (action.Cmd == WELD_ACTION.圆弧插补)
                {
                    maxX = action.Point1X + action.Radius;
                    maxY = action.Point1Y + action.Radius;
                }
                else
                {
                    continue;
                }

                maxX += (padding + originX);
                maxY += (padding + originY);

                CalculateDivisor(maxX, maxY, ref div);
            }

            divisor = div;
        }

        private void CalculateDivisor(int maxX, int maxY, ref float div)
        {
            float divisorX = 1;
            float divisorY = 1;
            if (maxX > this.Size.Width)
            {
                divisorX = (float)maxX / (float)this.Size.Width;
            }
            if (maxY > this.Size.Height)
            {
                divisorY = (float)maxY / (float)this.Size.Height;
            }

            if (div < Math.Max(divisorX, divisorY))
            {
                div = Math.Max(divisorX, divisorY);
            }
        }

        private void AnalyseMode(ActionParas action, out float startX, out float startY, out float endX, out float endY)
        {
            switch (action.Mode)
            {
                case 1:
                    startX = action.Point1X;
                    startY = action.Point1Y + action.Radius;
                    endX = action.Point1X + action.Radius;
                    endY = action.Point1Y;
                    break;
                case 2:
                    startX = action.Point1X - action.Radius;
                    startY = action.Point1Y;
                    endX = action.Point1X;
                    endY = action.Point1Y + action.Radius;
                    break;
                case 3:
                    startX = action.Point1X;
                    startY = action.Point1Y - action.Radius;
                    endX = action.Point1X - action.Radius;
                    endY = action.Point1Y;
                    break;
                case 4:
                    startX = action.Point1X + action.Radius;
                    startY = action.Point1Y;
                    endX = action.Point1X;
                    endY = action.Point1Y - action.Radius;
                    break;
                case 5:
                    startX = action.Point1X + action.Radius;
                    startY = action.Point1Y;
                    endX = action.Point1X;
                    endY = action.Point1Y + action.Radius;
                    break;
                case 6:
                    startX = action.Point1X;
                    startY = action.Point1Y + action.Radius;
                    endX = action.Point1X - action.Radius;
                    endY = action.Point1Y;
                    break;
                case 7:
                    startX = action.Point1X - action.Radius;
                    startY = action.Point1Y;
                    endX = action.Point1X;
                    endY = action.Point1Y - action.Radius;
                    break;
                case 8:
                    startX = action.Point1X;
                    startY = action.Point1Y - action.Radius;
                    endX = action.Point1X + action.Radius;
                    endY = action.Point1Y;
                    break;
                default:
                    startX = action.Point1X;
                    startY = action.Point1Y;
                    endX = action.Point1X;
                    endY = action.Point1Y;
                    break;
            }
            startX += CWeldController.mDockSetParameter.originXSet;
            startY += CWeldController.mDockSetParameter.originYSet;
            endX += CWeldController.mDockSetParameter.originXSet;
            endY += CWeldController.mDockSetParameter.originYSet;
        }

        public void AddToDrawList(DrawObject drawObject)
        {
            drawList.Add(drawObject);
        }

        private void DrawArea_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            SolidBrush brush = new SolidBrush(Color.FromArgb(255, 255, 255));
            g.FillRectangle(brush, this.ClientRectangle);
            g.SmoothingMode = SmoothingMode.AntiAlias;

            // 绘制坐标系
            Pen pen1 = new Pen(Color.Silver, 4);
            pen1.EndCap = LineCap.ArrowAnchor;
            g.DrawLine(pen1, 0, 0, this.Size.Width - 20, 0);
            g.DrawString("x", Font, new SolidBrush(Color.Silver), this.Size.Width - 20, 0);
            g.DrawLine(pen1, 0, 0, 0, this.Size.Height-20);
            g.DrawString("y", Font, new SolidBrush(Color.Silver), 0, this.Size.Height - 20);

            // 绘制说明信息
            pen1.Color = Color.Black;
            pen1.Width = 2;
            pen1.DashStyle = DashStyle.Dash;
            g.DrawLine(pen1, this.Size.Width - 100, this.Size.Height - 75, this.Size.Width - 80, this.Height - 75);
            g.DrawString(":非插补移动", Font, new SolidBrush(Color.Silver), this.Size.Width - 75, this.Size.Height - 80);
            pen1.DashStyle = DashStyle.Solid;
            g.DrawLine(pen1, this.Size.Width - 100, this.Size.Height - 60, this.Size.Width - 80, this.Height - 60);
            g.DrawString(":插补移动", Font, new SolidBrush(Color.Silver), this.Size.Width - 75, this.Size.Height - 65);
            pen1.Width = 4;
            pen1.DashStyle = DashStyle.Dash;
            g.DrawLine(pen1, this.Size.Width - 100, this.Size.Height - 45, this.Size.Width - 80, this.Height - 45);
            g.DrawString(":Z轴压下", Font, new SolidBrush(Color.Silver), this.Size.Width - 75, this.Size.Height - 50);
            pen1.Color = Color.Orange;
            pen1.DashStyle = DashStyle.Solid;
            g.DrawLine(pen1, this.Size.Width - 100, this.Size.Height - 30, this.Size.Width - 80, this.Height - 30);
            g.DrawString(":点胶开启", Font, new SolidBrush(Color.Silver), this.Size.Width - 75, this.Size.Height - 35);
            pen1.Color = Color.Green;
            pen1.Width = 1;
            g.FillEllipse(new SolidBrush(Color.Green), this.Size.Width - 95, this.Size.Height - 20, 8, 8);
            g.DrawString(":原点", Font, new SolidBrush(Color.Silver), this.Size.Width - 75, this.Size.Height - 20);
            
            // 绘制Action动作图形
            if ((drawList == null) || (drawList.Count == 0))
            {
                return;
            }
            foreach (DrawObject drawObject in drawList)
            {
                drawObject.Draw(g);
            }

            // 绘制当前坐标点
            ResourceManager rm = new ResourceManager("nsWeldController.Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
            g.DrawIcon((Icon)rm.GetObject("PointCurrent"), (int)(pointCurrent.X / divisor) - 6, (int)(pointCurrent.Y / divisor) - 6);

            brush.Dispose();
        }

        private void DrawArea_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Point point = e.Location;
                foreach (DrawObject drawObject in drawList)
                {
                    if (drawObject.IsPointInObject(point))
                    {
                        drawObject.selected = true;
                    }
                    else
                    {
                        drawObject.selected = false;
                    }
                    //drawObject.Draw(this.CreateGraphics());
                }
            }
            Refresh();
        }

        public void SetCurrentPoint(int x, int y)
        {
            pointCurrent.X = x;
            pointCurrent.Y = y;
        }
    }
}
